package ca.clarity.hms.activity;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;

import android.content.ContentValues;
import ca.clarity.hms.provider.HmsPatient;
import ca.clarity.hms.provider.HmsDatabaseHandler;
import ca.clarity.hms.util.HmsCommon;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.location.Location;
import android.location.LocationManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 환자 등록 화면.
 *
 * @author Junghun, Shin
 * @version 1.0
 */
public class HmsPatientRegistrationActivity extends Activity implements OnCompletionListener {

	public static String TAG = HmsPatientRegistrationActivity.class.getSimpleName();
	
	HmsCommon hmsCommon = new HmsCommon();
	
	HmsDatabaseHandler hmsDatabaseHandler;
	
    // 뒤로 가기 버튼.
    Button patientListBackButton;
    
    // Headshot 버튼.
    Button patientRegistrationHeadshotButton;
    
    // Interview 버튼.
    Button patientRegistrationInterviewButton;
    
    // Add a photo 버튼.
    Button addPhotoPatientRegistrationButton;
    
    // Record a interview 버튼.
    Button recordInterviewPatientRegistrationButton;
    
    // Headshot Thumbnail.
    ImageView headshotThumbnailImageView;
    
    // interview 재생 버튼.
    Button playInterviewPatientRegistrationButton;
    
    // Save 버튼.
    Button savePatientRegistrationButton;
    
    // 위도.
    TextView registrationPatientLatitudeTextView;

    // 경도.
    TextView registrationPatientLongitudeTextView;

    // 네트워크 정보.
    TextView registrationPatientNetworkTextView;

    // 메모리 정보.
    TextView registrationPatientMemoryTextView;
    
    // 현재 위치를 가져온다.
    private static final int THREAD_LOCATION = 101;

    // 네트워크 연결상태를 가져 온다.
    private static final int THREAD_IS_ONLINE = 102;

    // 사용가능한 메모리 사용량을 가져 온다.
    private static final int THREAD_AVAILABLE_MEMORY = 103;
    
    // Headshot 화면을 출력 한다.
    private static final int THREAD_SHOW_HEADSHOT_LAYOUT = 104;
    
    // Interview 화면을 출력 한다.
    private static final int THREAD_SHOW_INTERVIEW_LAYOUT = 105;
    
    // Headshot, interview 를 저장 한다.
    private static final int THREAD_SAVE_PATIENT = 106;
    
    // Headshot 화면.
    LinearLayout patientRegistrationHeadshotLinearLayout;
    
    // Interview 화면.
    LinearLayout patientRegistrationInterviewLinearLayout;
    
    // 사진 찍기.
    private static final int REQUEST_PHOTO = 106;
    
    // 앨범에서 사진 가져 오기.
    private static final int REQUEST_ALBUM = 107;
    
    // interview 를 재생한다.
 	private static final int THREAD_PLAY_INTERVIEW = 108;
 	
 	// record interview activity 결과 코드.
 	private static final int REQUEST_INTERVIEW = 109;
 	
 	// play a interview 버튼을 텍스트를 수정 한다.
 	private static final int THREAD_SET_TEXT_PLAY_A_INTERVIEW_BUTTON = 110;
    
    // 촬영 또는 앨범에서 선택한 이미지.
    Bitmap mySelectedImage = null;
    
    // 사진 파일명.
    private String SAMPLEIMG = hmsCommon.getCurrentTimeMillis() + ".png";
    
    // 녹음 중인 임시파일이 저장될 경로.
 	String applicationAudioTempDirectory = "/Android/data/ca.clarity.hms.activity/.AudioRecord/temp";
 	
 	// 녹음 음성 재생기
 	private MediaPlayer mPlayer = null;
 	
 	// interview 파일명.
 	public String interviewFileName = "";
 	
 	/**
 	 * 
 	 * @return
 	 */
 	public String tempMP3FileName() {
		// 디렉토리 없으면 생성
		File file = new File(Environment.getExternalStorageDirectory().getPath(), applicationAudioTempDirectory);
		
		if(!file.exists()){
			file.mkdirs();
		}
		
		return Environment.getExternalStorageDirectory() + applicationAudioTempDirectory + "/" + interviewFileName;		
	}

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 커스텀 타이틀 바를 설정 한다.
        Window window = getWindow();
        window.requestFeature(Window.FEATURE_CUSTOM_TITLE);

        setContentView(R.layout.activity_hms_patient_registration);

        window.setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_bar_patient_registration);

        // 뒤로 가기 버튼.
        patientListBackButton = (Button) findViewById(R.id.patientListBackButton);
        patientListBackButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        
        // Headshot layout.
        patientRegistrationHeadshotLinearLayout = (LinearLayout)findViewById(R.id.patientRegistrationHeadshotLinearLayout);
        
        // Interview layout.
        patientRegistrationInterviewLinearLayout = (LinearLayout)findViewById(R.id.patientRegistrationInterviewLinearLayout);
        
        // Headshot Thumbnail.
        headshotThumbnailImageView = (ImageView)findViewById(R.id.headshotThumbnailImageView);
                
        // 위도.
        registrationPatientLatitudeTextView = (TextView) findViewById(R.id.registrationPatientLatitudeTextView);

        // 경도.
        registrationPatientLongitudeTextView = (TextView) findViewById(R.id.registrationPatientLongitudeTextView);

        // 네트워크 정보.
        registrationPatientNetworkTextView = (TextView) findViewById(R.id.registrationPatientNetworkTextView);

        // 메모리 정보.
        registrationPatientMemoryTextView = (TextView) findViewById(R.id.registrationPatientMemoryTextView);
        
        // 현재 위치를 가져 온다.
        mHandler.sendMessage(mHandler.obtainMessage(THREAD_LOCATION));

        // 네트워크 연결상태를 가져 온다.
        mHandler.sendMessage(mHandler.obtainMessage(THREAD_IS_ONLINE));

        // 사용가능한 메모리 양을 가져 온다.
        mHandler.sendMessage(mHandler.obtainMessage(THREAD_AVAILABLE_MEMORY));
        
        // Headshot 버튼.
        patientRegistrationHeadshotButton = (Button)findViewById(R.id.patientRegistrationHeadshotButton);
        patientRegistrationHeadshotButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// Headshot 화면을 출력 한다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_SHOW_HEADSHOT_LAYOUT));
			}
        	
        });
        
        // Interview 버튼.
        patientRegistrationInterviewButton = (Button)findViewById(R.id.patientRegistrationInterviewButton);
        patientRegistrationInterviewButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// Interview 화면을 출력 한다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_SHOW_INTERVIEW_LAYOUT));
			}
        	
        });
        
        // Add a photo 버튼.
        addPhotoPatientRegistrationButton = (Button)findViewById(R.id.addPhotoPatientRegistrationButton);
        addPhotoPatientRegistrationButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// 사진 찍거나 앨범에서 가져오기 메뉴를 띄운다.
				openCameraGallary();
			}
        	
        });
        
        // Record a interview 버튼.
        recordInterviewPatientRegistrationButton = (Button)findViewById(R.id.recordInterviewPatientRegistrationButton);
        recordInterviewPatientRegistrationButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// 기본적인 녹음기능을 연다.
				Intent i = new Intent(HmsPatientRegistrationActivity.this, HmsRecordInterviewActivity.class);
//				startActivity(i);
				startActivityForResult(i, REQUEST_INTERVIEW);
			}
        	
        });
        
        // Play a interview 버튼.
        playInterviewPatientRegistrationButton = (Button)findViewById(R.id.playInterviewPatientRegistrationButton);
        playInterviewPatientRegistrationButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// interview 를 재생한다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_PLAY_INTERVIEW));
			}
        	
        });
        
        // Save 버튼.
        savePatientRegistrationButton = (Button)findViewById(R.id.savePatientRegistrationButton);
        savePatientRegistrationButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// photo, interview 를 저장 한다.
				mHandler.sendMessage(mHandler.obtainMessage(THREAD_SAVE_PATIENT));
			}
        	
        });
        
        // 기본적으로 Headshot 화면을 출력 한다.
        mHandler.sendMessage(mHandler.obtainMessage(THREAD_SHOW_HEADSHOT_LAYOUT));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.hms_village, menu);
        return true;
    }

    /**
     * Handler 를 정의한다.
     * 모든 Thread 를 등록해 놓고 필요할때 호출한다.
     */
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case THREAD_LOCATION:
                    getLocationInformation();
                    break;
                case THREAD_IS_ONLINE:
                    isOnline();
                    break;
                case THREAD_AVAILABLE_MEMORY:
                    getCurrentMemory();
                    break;
                case THREAD_SHOW_HEADSHOT_LAYOUT : 
                	patientRegistrationHeadshotLinearLayout.setVisibility(View.VISIBLE);
                	patientRegistrationInterviewLinearLayout.setVisibility(View.INVISIBLE);
                	
                	break;
                case THREAD_SHOW_INTERVIEW_LAYOUT : 
                	patientRegistrationHeadshotLinearLayout.setVisibility(View.INVISIBLE);
                	patientRegistrationInterviewLinearLayout.setVisibility(View.VISIBLE);
                	break;
                case THREAD_SAVE_PATIENT : 
                	savePatient();
                	break;
                case THREAD_PLAY_INTERVIEW : 
                	runOnUiThread(playRecording);
                	break;
                case THREAD_SET_TEXT_PLAY_A_INTERVIEW_BUTTON : 
                	break;
            }
        }
    };
    
    /**
     * 사진관련 이벤트.
     */
    private void openCameraGallary() {
    	// 이미지 선택 다이얼로그
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setTitle("Choose a menu");
    	builder.setItems(R.array.choice_photo_image, new DialogInterface.OnClickListener() {
    		@Override
    		public void onClick(DialogInterface dialog, int which) {
    	   
    			switch (which) {
    			case 0:
    				// 카메라 촬영
    				takePicture();
    				break;
    			case 1:
    				// 이미지 선택
    				photoAlbum();
    				break;
    			}
    		}
    	});

    	builder.show();
    }
    
    //사진 촬영을 한다.
  	void takePicture() {
  		//카메라 호출 intent 생성
  		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  		startActivityForResult(intent, REQUEST_PHOTO);
  	}
  	
  	//앨범에서 사진을 불러온다.
  	void photoAlbum() {
  		//photo Album 호출 intent 생성
  		Intent intent = new Intent(Intent.ACTION_PICK);
  		intent.setType(Images.Media.CONTENT_TYPE);
  		intent.setData(Images.Media.EXTERNAL_CONTENT_URI);
  		startActivityForResult(intent, REQUEST_ALBUM);
  	}
  	
  	//촬영한 사진을 수정한다.
  	Bitmap loadPicture() {
  		File file = new File(Environment.getExternalStorageDirectory(), SAMPLEIMG);
  		BitmapFactory.Options option = new BitmapFactory.Options();
  		option.inSampleSize = 4;
  		return BitmapFactory.decodeFile(file.getAbsolutePath(), option);
  	}
  	
  	// 촬영했거나 앨범에서 가져온 사진을 처리 한다.
  	@Override
  	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  		// 촬영한 사진을 처리 한다.
  		if (requestCode == REQUEST_PHOTO) {
  			mySelectedImage = (Bitmap)data.getExtras().get("data");
  			Log.i(TAG, "take photo");
  			
  			// 사진을 database 에 저장한다?
  			
  			// 사진을 imageiView 에 썸네일로 출력 한다. 
  			headshotThumbnailImageView.setImageBitmap(mySelectedImage);
  			
  			// bitmap 을 byte 로 변환 한다.
  			ByteArrayOutputStream stream = new ByteArrayOutputStream();
  			mySelectedImage.compress(CompressFormat.PNG, 50, stream);
  			byte[] byteArray = stream.toByteArray();
  			
  			HmsPatient hmsPatient = new HmsPatient();
  			
  			hmsPatient.setPhoto(byteArray);
  		}
  		
  		// 앨범에서 가져온 사진을 처리 한다.
  		if(requestCode == REQUEST_ALBUM) {
  			Uri curImgURI = data.getData();
  			try {
  				mySelectedImage = Images.Media.getBitmap(getContentResolver(), curImgURI );
  				Log.i(TAG, "album photo");
  				
  				// 앨범에서 가져온 사진을 database 에 저장한다?
  				
  				// 사진을 imageiView 에 썸네일로 출력 한다. 
  				headshotThumbnailImageView.setImageBitmap(mySelectedImage);
  				
  				// bitmap 을 byte 로 변환 한다.
  	  			ByteArrayOutputStream stream = new ByteArrayOutputStream();
  	  			mySelectedImage.compress(CompressFormat.PNG, 100, stream);
  	  			byte[] byteArray = stream.toByteArray();
  	  			
  	  			HmsPatient hmsPatient = new HmsPatient();
  	  			
  	  			hmsPatient.setPhoto(byteArray);
  				
  			} catch(Exception e) {
  				
  			}
  		}
  		
  		// interview 녹음하고 화면을 닫았을때.
  		if(requestCode == REQUEST_INTERVIEW) {
  			try {
  				if(data.getStringExtra("interviewFullFilePath") != null) {
  	  				interviewFileName = data.getStringExtra("interviewFullFilePath");
  	  	  			
  	  	  			// play 버튼의 텍스트를 수정 한다.
  	  	  			if(!("").equals(interviewFileName)) {
  	  	  				mHandler.sendMessage(mHandler.obtainMessage(THREAD_SET_TEXT_PLAY_A_INTERVIEW_BUTTON));
  	  	  			}
  	  			}
  			} catch(Exception e) {
  				
  			}
  		}
  	}
  	
  	/**
  	 * Headshot, interview 를 저장 한다.
  	 */
  	public void savePatient() {
  		hmsDatabaseHandler = HmsDatabaseHandler.open(getApplicationContext());
  		
  		hmsDatabaseHandler.beginTransaction();
  		
  		try {
  			// database 에 저장 한다.
	  		ContentValues values = new ContentValues();
	  		
  			HmsPatient hmsPatient = new HmsPatient();
  			
  			// bitmap 을 byte 로 변환 한다.
	  		if(mySelectedImage != null) {
	  			ByteArrayOutputStream stream = new ByteArrayOutputStream();
		  		mySelectedImage.compress(CompressFormat.PNG, 100, stream);
		  		byte[] byteArray = stream.toByteArray();
		  			
		  		hmsPatient.setPhoto(byteArray);
		  		
		  		values.put("photo", hmsPatient.getPhoto());
	  		}
	  		
	  		// mp3 를 byte 로 변환 한다.
	  		if(!("").equals(interviewFileName)) {
	  			File file = new File(interviewFileName);
		  		FileInputStream in = new FileInputStream(file);
		  		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		  		
		  		byte[] by = new byte[(int)file.length()];
		  		int len = 0;

		  		while( (len=in.read(by)) != -1) {
		  			bout.write(by, 0, len);
		  		}

		  		byte[] interviewBytes = bout.toByteArray();
		  		bout.close();
		  		in.close();

		  		hmsPatient.setInterview(interviewBytes);
		  		
		  		values.put("interview", hmsPatient.getInterview());
	  		}
	  		
	  		hmsDatabaseHandler.insertHmsPatient(values);
	  		
	  		ArrayList<HmsPatient> patientList = hmsDatabaseHandler.selectPatientList();
	  		Log.i(TAG, "patientList size : " + patientList.size());
  			
  		} catch(Exception e) {
  			
  		} finally {
  			hmsDatabaseHandler.endTransaction();
  		}
  		
  		if(hmsDatabaseHandler != null) {
  			hmsDatabaseHandler.close();
  		}
  	}
    
  	/**
	 * 녹음한 음성을 재생한다
	 */
	private Runnable playRecording = new Runnable() {
		@Override
		public void run() {
			// 음성을 재생한다
			initMediaPlayer();
			startPlay();
		}
	};
	
	/**
	 * 미디어 플레이어를 초기화 한다.
	 */
	private void initMediaPlayer() {
		// 미디어 플레이어 생성
		if(mPlayer == null) {
			mPlayer = new MediaPlayer();
		} else{
			mPlayer.reset();
		}
		
		mPlayer.setOnCompletionListener(this);
		
		try {
			if(!("").equals(interviewFileName)) {
				mPlayer.setDataSource(interviewFileName);
				mPlayer.prepare();
			}
		} catch(Exception e) {
			
		}
	}
	
	/**
	 * interview 를 재생한다.
	 */
	private void startPlay() {
		
		if(!("").equals(interviewFileName)) {
			try {
				Log.i(TAG, "startPlay fullFilePath : " + interviewFileName);
				
				mPlayer.start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * interview 재생버튼의 텍스트를 재생할 파일명으로 수정 한다.
	 */
	public void setTextPlayAInterviewButton() {
		String asIs = playInterviewPatientRegistrationButton.getText().toString();
		playInterviewPatientRegistrationButton.setText(asIs + " : " + hmsCommon.getCurrentDateFromMillis(interviewFileName));
	}
  	
  	
  	
    
    
    
  	
  	
  	
  	
    
    
    
    
    
    
    /**
     * 현재 위치의 위도, 경도를 구한다.
     */
    public void getLocationInformation() {

        // 위도, 경도는 소숫점 두자리까지 구한다. 소숫점 셋째자리 이하는 반올림으로 처리 한다.
        String pattern = ".##";

        DecimalFormat decimalFormat = new DecimalFormat(pattern);

        LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

        // 화면에 출력 한다.
        registrationPatientLatitudeTextView.setText(decimalFormat.format(location.getLatitude()) + "");
        registrationPatientLongitudeTextView.setText(decimalFormat.format(location.getLongitude()) + "");
    }

    /**
     * 네트워크 연결상태를 확인 한다.
     *
     * @return
     */
    private void isOnline() {

        String result;

        try {
            ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo.State wifi = conMan.getNetworkInfo(1).getState(); // wifi

            NetworkInfo.State mobile = conMan.getNetworkInfo(0).getState(); // mobile ConnectivityManager.TYPE_MOBILE

            if (wifi == NetworkInfo.State.CONNECTED || wifi == NetworkInfo.State.CONNECTING) {
                result = "Connected";
            } else if (mobile == NetworkInfo.State.CONNECTED || mobile == NetworkInfo.State.CONNECTING) {
                result = "Connected";
            } else {
                result = "Not Connected";
            }

        } catch (NullPointerException e) {
            result = "Not Connected";
        }

        // 화면에 출력 한다.
        registrationPatientNetworkTextView.setText(result);
    }

    /**
     * 사용가능한 메모리를 가져 온다.
     */
    private void getCurrentMemory() {
        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        activityManager.getMemoryInfo(mi);
        long availableMegs = mi.availMem / 1048576L;

        // 화면에 출력 한다.
        registrationPatientMemoryTextView.setText(availableMegs + " M");
    }

	@Override
	public void onCompletion(MediaPlayer mp) {
		// TODO Auto-generated method stub
		
	}
}
